#ifndef MSGPACKAGE_H
#define MSGPACKAGE_H

// 类名：MsgPackage
// 该类主要为网络通讯的封包协议，类代表一个封包的完整数据
// 2022/12/18
//
// 包的格式为：
// {
//    QByteArray sig;       // [4字节] 头标志
//    quint8 checkSum;      // [1字节] 校验和（将完整包带入校验）
//    quint32  len;         // [4字节] pkgData长度
//    QByteArray pkgData;   // [n字节] 包含的数据内容
// }


#include <QByteArray>

#define MAX_DATA_LEN 10 * 1024 * 8       //数据长度阈值为10M

class MsgPackage
{
public:
    MsgPackage();
    virtual ~MsgPackage();

    // 获取固定的协议包头长度
    int headerLength();

    // 清理包头和包内容数据
    void clearPkg();

    // 拆包函数
    void unPkg(QByteArray data);

    // 组包函数
    QByteArray mkPkg(QByteArray data);

    // 虚函数 继承的子类必须重新实现
    virtual void pkgReady(QByteArray data){};

public:

    bool isCheckSum = false;            //是否验证校验和

private:

    // 内部函数，查找包头的位置，未找到返回-1
    int seekHeader(QByteArray data, int from = 0);

    // 内部函数，int转QByteArray
    QByteArray intToBytes(int i);

    // 内部函数，QByteArray转int
    quint32 bytesToInt(QByteArray bytes);

    // 内部函数，计算校验和
    quint8 getCheckSum(QByteArray data);

    // 内部函数，检测包的状态
    int checkWhatToDo();

    // 内部函数，检测校验和是否正确
    void checkSum(QByteArray data);

    // 内部函数，初始化头标志
    void initHeadSymbol();

private:
    QByteArray sig;             //头标志
    quint32 len;                //数据长度
    quint8 checksum;            //校验和
    QByteArray pkgData;         //包数据内容
    QByteArray tmpPkgData;      //临时数据，用拼接上一次的包数据，进入下一次循环迭代处理
};

#endif // MSGPACKAGE_H
